const Parser = require("./parser");
const Node = require("./Node");

function parse(content) {
  const stack = []; // 存储标签的栈, 父子结构的处理栈

  const parser = new Parser(content);
  const root = new Node();
  root.start = parser.index;
  root.type = "Fragment";

  const attr_value = function () {
    // todo: 可以判断一些特殊的属性 : 等等
    if (parser.next('=') && parser.next('"')) {
      const value = parser.readStr('"');
      parser.next('"');
      return {
        value,
        type: "Attribute"
      }
    }
  }
  const attrs = function (node) {
    parser.skip();
    if (
      parser.current() === ">" ||
      parser.current() === "/"
      && parser.current() !== ' ') { // parser.current() === "/" 是自闭合标签的 /
      return;
    }

    const attrName = parser.readStr('=');

    node.attrs.push({
      key: attrName,
      ...attr_value()
    });

    parser.skip();

    while (parser.current() !== ">" && parser.current() !== "/") {
      attrs(node)
    }
  }

  const tag_name_close = function () {
    const tagName = parser.readStr(">");

    const current_node = stack.pop();
    current_node.end = parser.index;

    parser.next(">")

    if (current_node.name !== tagName) {
      throw new Error(`${current_node.name},标签没有匹配到,${tagName}`);
    }
  }

  const tag_name = function () {
    const node = new Node();
    node.start = parser.index;
    const tagName = parser.regReadStr(/\s+|\>/);
    node.name = tagName;
    node.type = "Element";

    // todo: attrs
    attrs(node);

    if (parser.next(">")) {
      stack.push(node);
      return node;
    } else if (parser.next("/>")) {
      stack.pop();
      node.selfClosing = true;
      node.end = parser.index;
    }
    return node;
  }

  const text = function () {
    const node = new Node();
    node.start = parser.index;
    const text = parser.regReadStr(/\<|{/);
    // const text = parser.readStr("<");
    node.data = text;
    node.end = parser.index;
    node.type = "Text";
    return node;
  }

  const block_open = function () {
    const keywords = ['if', 'each'];
    const node = new Node();
    node.start = parser.index;

    const blockName = parser.readStr(" ");
    // console.log('blockName', blockName)
    if (!keywords.includes(blockName)) {
      throw new Error(blockName + ' 是不合法的关键字')
    }

    const blockType = keywords[keywords.findIndex(val => val === blockName)];
    node.type = blockType[0].toUpperCase() + blockType.slice(1) + "Block"; // IfBlock, EachBlock
    console.log("node.type", node.type)

    stack.push(node);
    if (node.type === 'IfBlock') {
      parser.skip();
      const condition = parser.readStr("}");
      console.log("condition: ", condition)
      node.data = {
        condition: condition.trim()
      }
    }

    if (node.type === 'EachBlock') {
      parser.skip();
      const variable = parser.readStr(" ");
      parser.skip();

      if (parser.next('as')) {
        const local = parser.regReadStr(/\,|\}/);
        if (parser.next(",")) {
          parser.skip();
          const index = parser.readStr("}");
          node.data = {
            variable: variable,
            local,
            index,
          };
        } else {
          node.data = {
            variable: variable,
            local,
          };
        }
      } else {
        throw new Error("as关键字不存在")
      }
    }


    if (parser.next("}")) {
      return node;
    } else {
      throw new Error("没有结束标签")
    }
  }

  const block_close = function () {
    const current_node = stack.pop();
    const blockName = current_node.type; // IfBlock EachBlock
    const name = parser.readStr("}");
    // if tag match
    if (blockName.replace("Block", "").toLowerCase() !== name) {
      throw new Error("Block 没有对应匹配到!");
    }
    parser.next("}"); // block 的结束标签
    current_node.end = parser.index;

  }

  // 匹配  {age} {name}
  const parse_mustache = function () {
    const tag = {
      type: "MustacheTag",
      start: parser.index,
      end: parser.index,
    };

    parser.skip();
    const name = parser.readStr("}");
    parser.next("}");
    return {
      ...tag,
      name: name.trim(),
      end: parser.index,
    };
  }

  const parseHTML = function () {
    let ch = parser.current();
    parser.skip();
    while (((ch = parser.current()), ch)) {
      let current_node = null;
      if (stack.length === 0) {
        current_node = root;
      } else {
        current_node = stack.slice(-1)[0];
      }

      if (parser.next("</")) {
        tag_name_close();
        parseHTML();
      } else if (parser.next("<")) {
        current_node.children.push(tag_name());
      } else if (parser.next("{#")) {
        current_node.children.push(block_open());
      } else if (parser.next("{/")) {
        // {/if} {/each}  结束
        block_close();
        parseHTML();
      } else if (parser.next("{")) {
        // 模板中的 {name}   {age}
        current_node.children.push(parse_mustache());
      } else {
        current_node.children.push(text());
      }
    }
    parser.skip();
    root.end = parser.index;
    return root;
  }

  return parseHTML();
}
module.exports = parse;
